package com.mida.app.knw.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.mida.app.knw.enumData.CharacterConstant;
import com.mida.app.knw.service.DetailCodingSystemService;
import com.mida.app.knw.service.KnwIndividualService;
import com.mida.dms.knw.api.KnwIndividualApi;
import com.mida.dms.knw.entity.vo.*;
import com.mida.dms.knw.vo.IndividualParmVo;
import com.mida.dms.knw.vo.KnwIndividualPageVo;
import com.mida.dms.knw.vo.Page;
import com.mida.dms.knw.vo.PageResultVo;
import com.mida.dms.mdm.param.DataSetPageParam;
import com.mida.dms.mdm.pojo.auto.MsdDataSet;
import com.mida.tool.common.result.ActionResult;
import com.mida.tool.common.result.ListResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.mida.tool.common.result.BaseResult.*;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class KnwIndividualServiceImpl implements KnwIndividualService {
    @Autowired
    private KnwIndividualApi knwIndividualApi;
    @Autowired
    private DetailCodingSystemService detailCodingSystemService;

    /**
     * arrayLists
     */
    private List<String[]> arrayLists;

    @Override
    public ActionResult delete(long soid) {
        return knwIndividualApi.delete(soid);
    }

    @Override
    public ActionResult stopSize(String soids) {
        return knwIndividualApi.stopSize(soids);
    }

    @Override
    public ActionResult openSize(String soids) {
        return knwIndividualApi.openSize(soids);
    }

    @Override
    public ListResult<PageResultVo<KnwIndividualVo>> findPage(KnwIndividualPageVo vo) {
        ListResult result = new ListResult();
        ListResult<PageResultVo<KnwIndividualVo>> page = null;
        try {
            page = knwIndividualApi.findPage(vo);
            if (ObjectUtils.isNotEmpty(page)) {
                PageResultVo<KnwIndividualVo> data = page.getData();
                if (ObjectUtils.isNotEmpty(data)) {
                    Page page1 = data.getPage();
                    if (ObjectUtils.isNotEmpty(page1) && ObjectUtils.isNotEmpty(page1.getTotalCount())) {
                        Integer totalCount = page1.getTotalCount();
                        if (ObjectUtils.isNotEmpty(totalCount) && totalCount > 0) {
                            List<KnwIndividualVo> list = data.getList();
                            list.stream().filter(knwIndividualVo -> ObjectUtils.isNotEmpty(knwIndividualVo.getNoumenonType()) || ObjectUtils.isNotEmpty(knwIndividualVo.getStatus())).forEach(knwIndividualVo -> {
                                Long noumenonType = knwIndividualVo.getNoumenonType();
                                Long status = knwIndividualVo.getStatus();
                                String noumenonTypeName = detailCodingSystemService.getDataSetName(noumenonType);
                                String statusName = detailCodingSystemService.getDataSetName(status);
                                knwIndividualVo.setNoumenonTypeName(noumenonTypeName);
                                knwIndividualVo.setStatusName(statusName);

                                List<KnwIndividualSoltVo> listKnwIndividualSoltVo = knwIndividualVo.getListKnwIndividualSoltVo();
                                if (CollectionUtils.isNotEmpty(listKnwIndividualSoltVo)) {
                                    listKnwIndividualSoltVo.stream().filter(knwIndividualSoltVo -> CollectionUtils.isNotEmpty(knwIndividualSoltVo.getList())).forEach(knwIndividualSoltVo -> {
                                        List<SoltVo> soltVos = knwIndividualSoltVo.getList();
                                        if (CollectionUtils.isNotEmpty(soltVos)) {
                                            for (SoltVo soltVo : soltVos) {
                                                Long dataSetSoid = soltVo.getDataSetSoid();
                                                String dataSetName = detailCodingSystemService.getDataSetName(dataSetSoid);
                                                soltVo.setDataSetName(dataSetName);
                                                Long derailCodingSystemSoid = detailCodingSystemService.getDerailCodingSystemSoid(dataSetSoid);
                                                soltVo.setDerailCodingSystemSoid(derailCodingSystemSoid);
                                            }
                                            knwIndividualSoltVo.setDerailCodingSystemSoid(soltVos.get(0).getDerailCodingSystemSoid());
                                        }
                                    });
                                }
                            });
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("分页查询实例发生异常" + e.getMessage());
            buildListWarn(result, e);
        }
        return page;
    }

    @Override
    public ActionResult save(KnwIndividualVo t) {
        return knwIndividualApi.save(t);
    }

    @Override
    public ActionResult saveKnwIndividualSolt(KnwIndividualVos t) {
        return knwIndividualApi.saveKnwIndividualSolt(t);
    }


    @Override
    public ListResult<List<KnwSlotVo>> showIndividualInit(Long noumenonSoid) {
        ListResult<List<KnwSlotVo>> knwSlotVoListResult = knwIndividualApi.showIndividualInit(noumenonSoid);
        return knwSlotVoListResult;
    }

    @Override
    public ListResult getIndividualList(IndividualParmVo individualParmVo) {
        log.info("开始实例列表生成" + individualParmVo.getDerailCodingSystemSoids());
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult listResult = new ListResult();

        if (ObjectUtils.isEmpty(individualParmVo.getDerailCodingSystemSoids())) {
            log.error("编码体系soid不能为空");
            buildBadRequestListWarn(listResult, "编码体系soid不能为空");
            return listResult;
        }
        List<KnwSlotVo> list = null;
        List<String> listTmps = new ArrayList<>();
        List<KnwSlotVo> listKnwSlotVoTmp = null;

        ListResult<List<KnwSlotVo>> individualList = null;
        try {
            Map<Long, Object> map = new HashMap<>();
            Map<Long, Object> mapBasic = new HashMap<>();
            Map<String, Object> mapKnwSlotVo = new HashMap<>();
            Map<String, Object> mapKnwSlotVoOther = new HashMap<>();
            List<String> listStr = new ArrayList<>();
            String knNoumenonName = CharacterConstant.EMPTY;

            // 处理选中，本体slot下存在编码体系SOID
            String[] derailCodingSystemSoids;
            Map<String, Object> mapDerailCodingSystemSoid = new HashMap<>();
            if (StringUtils.isNotEmpty(individualParmVo.getDerailCodingSystemSoids())) {
                derailCodingSystemSoids =
                        individualParmVo.getDerailCodingSystemSoids().split(CharacterConstant.COMMA_SYMBOL);
                for (String str : derailCodingSystemSoids) {
                    mapDerailCodingSystemSoid.put(str, str);
                }
            }

            // 处理选中本体slot的slotSoid
            String[] slotSoids;
            LinkedHashMap<String, Object> mapIndividualRules = new LinkedHashMap<>();
            if (StringUtils.isNotEmpty(individualParmVo.getIndividualRules())) {
                slotSoids =
                        individualParmVo.getIndividualRules().split(CharacterConstant.UNDER_LINE);
                for (String str : slotSoids) {
                    if (StringUtils.isNotEmpty(str) && isNumeric(str)) {
                        mapIndividualRules.put(str, CharacterConstant.EMPTY);
                    } else {
                        mapIndividualRules.put(str, str);
                    }
                }
            }

            individualList = knwIndividualApi.getIndividualList(individualParmVo);
            if (ObjectUtils.isNotEmpty(individualList) && CollectionUtils.isNotEmpty(individualList.getData())) {
                listKnwSlotVoTmp = individualList.getData();
                listKnwSlotVoTmp.stream().filter(vo -> ObjectUtils.isNotEmpty(vo)).forEach(knwSlotVo -> {
                    //设置UnitName和UnitDescription
                    Long unit = knwSlotVo.getUnit();
                    MsdDataSet conceptSoidByDataSetSoid = detailCodingSystemService.getConceptSoidByDataSetSoid(unit);
                    String dataSetMeaning = conceptSoidByDataSetSoid.getDataSetMeaning();
                    knwSlotVo.setUnitName(dataSetMeaning);
                    String dataSetDescription = conceptSoidByDataSetSoid.getDataSetDescription();
                    knwSlotVo.setUnitDescription(dataSetDescription);
                    //设置DerailCodingSystemName
                    Long derailCodingSystemSoid = knwSlotVo.getDerailCodingSystemSoid();
                    String detailCodingName = detailCodingSystemService.getDetailCodingName(derailCodingSystemSoid);
                    knwSlotVo.setDerailCodingSystemName(detailCodingName);
                    //设置DataSetName和soid
                    DataSetPageParam dataSetPageParam = new DataSetPageParam();
                    dataSetPageParam.setDerailCodingSystemSoid(derailCodingSystemSoid);
                    ListResult<com.baomidou.mybatisplus.extension.plugins.pagination.Page<MsdDataSet>> listByDerailCodingSystemSoid = detailCodingSystemService.findListByDerailCodingSystemSoid(dataSetPageParam);
                    if (ObjectUtils.isNotEmpty(listByDerailCodingSystemSoid) && ObjectUtils.isNotEmpty(listByDerailCodingSystemSoid.getData())) {
                        com.baomidou.mybatisplus.extension.plugins.pagination.Page<MsdDataSet> data = listByDerailCodingSystemSoid.getData();
                        if (ObjectUtils.isNotEmpty(data) && CollectionUtils.isNotEmpty(data.getRecords())) {
                            List<MsdDataSet> records = data.getRecords();
                            records.stream().filter(msdDataSet -> ObjectUtils.isNotEmpty(msdDataSet)).forEach(mdDataSet -> {
                                String dataSetName = mdDataSet.getDataSetMeaning();
                                Long dataSetSoid = mdDataSet.getDataSetSoid();
                                knwSlotVo.setDataSetName(dataSetName);
                                knwSlotVo.setDataSetSoid(dataSetSoid);
                            });
                        }
                    }
                });
            }

            // 遍历处理结果集
            for (KnwSlotVo knwSlotVo : listKnwSlotVoTmp) {
                // 基数MAP
                if (mapBasic.get(knwSlotVo.getSlotSoid()) == null) {
                    mapBasic.put(knwSlotVo.getSlotSoid(), knwSlotVo.getBasic());
                }

                // 编码体系为空的场合
                if (knwSlotVo.getDerailCodingSystemSoid() == null
                        || mapDerailCodingSystemSoid.get(knwSlotVo.getDerailCodingSystemSoid().toString()) == null) {
                    // 没有编码体系的本体slot、map的SlotSoid设置
                    if (map.get(knwSlotVo.getSlotSoid()) == null) {
                        map.put(knwSlotVo.getSlotSoid(), knwSlotVo.getSlotSoid());
                    }
                    // 没有编码体系的本体slot、map的SLOT以及相关编码体系下值集的对象设置
                    if (mapKnwSlotVoOther.get(knwSlotVo.getSlotSoid().toString()) == null) {
                        mapKnwSlotVoOther.put(knwSlotVo.getSlotSoid().toString(), knwSlotVo);
                    }
                    continue;
                }

                if (mapKnwSlotVo.get(knwSlotVo.getSlotSoid()
                        + CharacterConstant.SIGN_FOR_SUBTRACTION + knwSlotVo.getDataSetSoid()) == null) {
                    mapKnwSlotVo.put(knwSlotVo.getSlotSoid()
                            + CharacterConstant.SIGN_FOR_SUBTRACTION + knwSlotVo.getDataSetSoid(), knwSlotVo);
                }

                if (mapKnwSlotVo.get(knwSlotVo.getSlotSoid()) == null) {
                    KnwSlotVo k = new KnwSlotVo();
                    BeanUtils.copyProperties(knwSlotVo, k);
                    k.setDataSetSoid(null);
                    k.setDataSetName(null);
                    mapKnwSlotVo.put(knwSlotVo.getSlotSoid().toString(), k);
                }

                if (StringUtils.isEmpty(knNoumenonName)) {
                    knNoumenonName = knwSlotVo.getNoumenonName();
                }

                if (map.get(knwSlotVo.getSlotSoid()) == null) {
                    map.put(knwSlotVo.getSlotSoid(), knwSlotVo.getSlotSoid()
                            + CharacterConstant.COMMA_SYMBOL + knwSlotVo.getSlotSoid()
                            + CharacterConstant.SIGN_FOR_SUBTRACTION + knwSlotVo.getDataSetSoid());
                } else {
                    String str = (String) map.get(knwSlotVo.getSlotSoid());
                    str += CharacterConstant.COMMA_SYMBOL + knwSlotVo.getSlotSoid()
                            + CharacterConstant.SIGN_FOR_SUBTRACTION + knwSlotVo.getDataSetSoid();
                    map.put(knwSlotVo.getSlotSoid(), str);
                }
            }

            Map<String, Object> mapTmp = new HashMap<String, Object>();
            Stack<String> stack;
            List<String[]> arrayLists = new ArrayList<String[]>();
            // 根据基数排列组合
            for (Map.Entry<Long, Object> entry : map.entrySet()) {
                String str = String.valueOf(entry.getValue());
                int basic = (int) mapBasic.get(entry.getKey());
                stack = new Stack<String>();
                for (int i = 1; i <= basic; i++) {
                    getBasicList(str.split(CharacterConstant.COMMA_SYMBOL), i, 0, 0, mapTmp, stack);
                }
            }
            // 排列组合
            doExchange(arrayLists);

            // 实例列表
            List<KnwIndividualVo> listKnwIndividualVo = new ArrayList<>();
            // 实例对象
            KnwIndividualVo knwIndividualVo = new KnwIndividualVo();
            // 实例slot列表
            List<KnwIndividualSoltVo> listKnwIndividualSoltVo =
                    new ArrayList<KnwIndividualSoltVo>();
            // 实例slot对象
            KnwIndividualSoltVo knwIndividualSoltVo;
            // 实例slot值列表
            List<SoltVo> listSoltVo = new ArrayList<SoltVo>();
            // 实例slot值对象
            SoltVo soltVo;

            // 遍历结果集设置返回前端的对象
            if (arrayLists != null && arrayLists.size() > 0) {
                Object object = arrayLists.get(0);

                List<String[]> lists;
                if (object instanceof String[]) {
                    lists = new ArrayList<String[]>();
                    String[] strs = (String[]) object;
                    for (String str : strs) {
                        String[] strTmp = new String[1];
                        strTmp[0] = str;
                        lists.add(strTmp);
                    }
                } else {
                    lists = (List<String[]>) object;
                }

                for (int i = 0; i < lists.size(); i++) {
                    Object obj = lists.get(i);
                    List<String> strList;
                    if (obj instanceof String[]) {
                        strList = new ArrayList<String>();
                        String[] strTmp = lists.get(i);
                        if (strTmp != null && strTmp.length > 0) {
                            strList.add(strTmp[0]);
                        }
                    } else {
                        strList = (List<String>) obj;
                    }

                    knwIndividualVo = new KnwIndividualVo();
                    knwIndividualVo.setNoumenonSoid(individualParmVo.getNoumenonSoid());
                    knwIndividualVo.setKnNoumenonName(knNoumenonName);
                    listKnwIndividualSoltVo =
                            new ArrayList<KnwIndividualSoltVo>();
                    String individualName = CharacterConstant.EMPTY;
                    for (int j = 0; j < strList.size(); j++) {
                        knwIndividualSoltVo = new KnwIndividualSoltVo();
                        String str = strList.get(j);
                        if (StringUtils.isNotEmpty(str)) {
                            String[] strs = str.split(CharacterConstant.COMMA_SYMBOL);
                            listSoltVo = new ArrayList<SoltVo>();
                            KnwSlotVo knwSlotVo = new KnwSlotVo();
                            for (String strTmp : strs) {
                                soltVo = new SoltVo();
                                if (mapKnwSlotVo.get(strTmp) != null) {
                                    knwSlotVo = (KnwSlotVo) mapKnwSlotVo.get(strTmp);
                                    soltVo.setBasic(Long.valueOf(knwSlotVo.getBasic()));
                                    soltVo.setDataSetSoid(knwSlotVo.getDataSetSoid());
                                    soltVo.setDataType(knwSlotVo.getDataType());
                                    soltVo.setDataSetName(knwSlotVo.getDataSetName());
                                    soltVo.setDerailCodingSystemSoid(knwSlotVo.getDerailCodingSystemSoid());
                                    listSoltVo.add(soltVo);
                                    if (knwSlotVo.getSlotSoid() != null) {
                                        if (mapIndividualRules.get(knwSlotVo.getSlotSoid().toString()) != null) {
                                            if (StringUtils.isNotEmpty(soltVo.getDataSetName())) {
                                                String individualNameTmp = (String) mapIndividualRules.get(knwSlotVo.getSlotSoid().toString());
                                                mapIndividualRules.put(knwSlotVo.getSlotSoid().toString(),
                                                        individualNameTmp + soltVo.getDataSetName());
                                            }
                                        }
                                    }
                                    continue;
                                }
                                if (mapKnwSlotVoOther.get(strTmp) != null) {
                                    knwSlotVo = (KnwSlotVo) mapKnwSlotVoOther.get(strTmp);
                                    soltVo.setBasic(Long.valueOf(knwSlotVo.getBasic()));
                                    soltVo.setDataType(knwSlotVo.getDataType());
                                    soltVo.setDerailCodingSystemSoid(knwSlotVo.getDerailCodingSystemSoid());
                                    listSoltVo.add(soltVo);
                                }
                            }

                            knwIndividualSoltVo.setSlotSoid(knwSlotVo.getSlotSoid());
                            knwIndividualSoltVo.setDerailCodingSystemSoid(knwSlotVo.getDerailCodingSystemSoid());
                            knwIndividualSoltVo.setDataType(knwSlotVo.getDataType());
                            knwIndividualSoltVo.setBasic(Long.valueOf(knwSlotVo.getBasic()));
                            knwIndividualSoltVo.setList(listSoltVo);
                        }
                        listKnwIndividualSoltVo.add(knwIndividualSoltVo);
                    }
                    knwIndividualVo.setIndividualName(knNoumenonName);

                    for (Map.Entry<String, Object> entry : mapIndividualRules.entrySet()) {
                        individualName += entry.getValue();
                        if (isNumeric(entry.getKey())) {
                            entry.setValue(CharacterConstant.EMPTY);
                        }
                    }

                    if (StringUtils.isNotEmpty(individualName)) {
                        knwIndividualVo.setIndividualName(individualName);
                    }

                    knwIndividualVo.setListKnwIndividualSoltVo(listKnwIndividualSoltVo);
                    listKnwIndividualVo.add(knwIndividualVo);
                }
            }
            buildListSuccess(listResult, listKnwIndividualVo);
        } catch (Exception e) {
            log.error("实例列表生成异常", e);
            buildListWarn(listResult, "实例列表生成失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时:" + stopWatch.getTime() + "ms");
        }
        return individualList;
    }

    @Override
    public ListResult<List<KnwIndividualVo>> findAll(KnwIndividualPageVo vo) {
        ListResult result = new ListResult();
        ListResult<List<KnwIndividualVo>> all = null;
        try {
            all = knwIndividualApi.findAll(vo);
            if (ObjectUtils.isNotEmpty(all)) {
                List<KnwIndividualVo> data = all.getData();
                if (ObjectUtils.isNotEmpty(data)) {
                    data.stream().filter(knwIndividualVo -> ObjectUtils.isNotEmpty(knwIndividualVo.getNoumenonType()) || ObjectUtils.isNotEmpty(knwIndividualVo.getStatus())).forEach(knwIndividualVo -> {
                        Long noumenonType = knwIndividualVo.getNoumenonType();
                        Long status = knwIndividualVo.getStatus();
                        String noumenonTypeName = detailCodingSystemService.getDataSetName(noumenonType);
                        String statusName = detailCodingSystemService.getDataSetName(status);
                        knwIndividualVo.setNoumenonTypeName(noumenonTypeName);
                        knwIndividualVo.setStatusName(statusName);


                        List<KnwIndividualSoltVo> listKnwIndividualSoltVo = knwIndividualVo.getListKnwIndividualSoltVo();
                        if (CollectionUtils.isNotEmpty(listKnwIndividualSoltVo)) {
                            listKnwIndividualSoltVo.stream().filter(knwIndividualSoltVo -> CollectionUtils.isNotEmpty(knwIndividualSoltVo.getList())).forEach(knwIndividualSoltVo -> {
                                List<SoltVo> list = knwIndividualSoltVo.getList();
                                if (CollectionUtils.isNotEmpty(list)) {
                                    for (SoltVo soltVo : list) {
                                        Long dataSetSoid = soltVo.getDataSetSoid();
                                        String dataSetName = detailCodingSystemService.getDataSetName(dataSetSoid);
                                        soltVo.setDataSetName(dataSetName);
                                        Long derailCodingSystemSoid = detailCodingSystemService.getDerailCodingSystemSoid(dataSetSoid);
                                        soltVo.setDerailCodingSystemSoid(derailCodingSystemSoid);
                                    }
                                }
                                knwIndividualSoltVo.setDerailCodingSystemSoid(list.get(0).getDerailCodingSystemSoid());
                            });
                        }

                    });
                }
            }
        } catch (Exception e) {
            log.error("分页查询实例发生异常" + e.getMessage());
            buildListWarn(result, e);
        }
        return all;
    }

    /**
     * 判断是否是数字
     *
     * @param str
     * @return
     */
    private static boolean isNumeric(String str) throws Exception {
        Pattern pattern = Pattern.compile(CharacterConstant.REGEX_IS_NUM);
        return pattern.matcher(str).matches();
    }

    /**
     * @param shu  元素
     * @param targ 要选多少个元素
     * @param has  当前有多少个元素
     * @param cur  当前选到的下标
     */
    private void getBasicList(String[] shu, int targ, int has, int cur, Map<String, Object> mapTmp, Stack<String> stack) throws Exception {

        if (has == targ) {
            String str = stack.get(0);
            String[] strs = str.split(CharacterConstant.SIGN_FOR_SUBTRACTION);
            List<String> listStr = new ArrayList<>();
            String strTmp = "";
            if (mapTmp.get(strs[0]) == null) {
                listStr.add(stack.stream()
                        .collect(Collectors.joining(CharacterConstant.COMMA_SYMBOL)));
                mapTmp.put(strs[0], listStr);
            } else {
                listStr = (List<String>) mapTmp.get(strs[0]);
                listStr.add(stack.stream()
                        .collect(Collectors.joining(CharacterConstant.COMMA_SYMBOL)));
                mapTmp.put(strs[0], listStr);
            }

            return;
        }

        for (int i = cur; i < shu.length; i++) {
            if (!stack.contains(shu[i])) {
                stack.add(shu[i]);
                getBasicList(shu, targ, has + 1, i, mapTmp, stack);
                stack.pop();
            }
        }

    }

    /**
     * 排列组合
     *
     * @param arrayLists
     */
    private void doExchange(List arrayLists) throws Exception {

        int len = arrayLists.size();
        //判断数组size是否小于2，如果小于说明已经递归完成
        if (len < 2) {
            this.arrayLists = arrayLists;
            return;
        }
        //拿到第一个数组
        int len0;
        if (arrayLists.get(0) instanceof String[]) {
            String[] arr0 = (String[]) arrayLists.get(0);
            len0 = arr0.length;
        } else {
            len0 = ((ArrayList<String>) arrayLists.get(0)).size();
        }

        //拿到第二个数组
        String[] arr1 = (String[]) arrayLists.get(1);
        int len1 = arr1.length;

        //计算当前两个数组一共能够组成多少个组合
        int lenBoth = len0 * len1;

        //定义临时存放排列数据的集合
        ArrayList<ArrayList<String>> tempArrayLists = new ArrayList<>(lenBoth);

        //第一层for就是循环arrayLists第一个元素的
        for (int i = 0; i < len0; i++) {
            //第二层for就是循环arrayLists第二个元素的
            for (int j = 0; j < len1; j++) {
                //判断第一个元素如果是数组的场合
                if (arrayLists.get(0) instanceof String[]) {
                    String[] arr0 = (String[]) arrayLists.get(0);
                    ArrayList<String> arr = new ArrayList<>();
                    arr.add(arr0[i]);
                    arr.add(arr1[j]);
                    //把排列数据加到临时的集合中
                    tempArrayLists.add(arr);
                } else {
                    //上一轮的结果继续跟arrayLists的下一个元素排列
                    ArrayList<ArrayList<String>> arrtemp = (ArrayList<ArrayList<String>>) arrayLists.get(0);
                    ArrayList<String> arr = new ArrayList<>();
                    for (int k = 0; k < arrtemp.get(i).size(); k++) {
                        arr.add(arrtemp.get(i).get(k));
                    }
                    arr.add(arr1[j]);
                    tempArrayLists.add(arr);
                }
            }
        }

        //根据上面排列的结果重新生成的一个集合
        List newArrayLists = new ArrayList<>();
        //排列的数组装进来，前面两个数组不需要再加进来了
        for (int i = 2; i < arrayLists.size(); i++) {
            newArrayLists.add(arrayLists.get(i));
        }
        //数据加到新集合的第一位
        newArrayLists.add(0, tempArrayLists);

        //递归
        doExchange(newArrayLists);
    }

}
